<html>
    <head>
        <title>应急方案</title>
    </head>
    <script>
        // 应急方案
                 /*
                    你的一些组件可能需要控制盒同步React之外的系统。
                    例如，你可能需要使用浏览器API聚焦输入、播放和暂停未使用React实现的视频播放器，或者连接并收听来自远程服务器的消息。
                    在本章中，你将学习让你"走出"React并连接到外部系统的应急方案。（大多数应用逻辑和数据流不应该依赖这些功能）
                 */

                 // 一、使用引用来应用值
                        /*
                            当你想要一个组件"记住"某些信息，但你不想让这些信息"触发渲染"，你可以使用一个"引用"
                        */
                            const ref = useRef(e);

                        /*
                            与状态一样，引用在重新渲染之间由React保留。
                            但是，设置状态会引发重新渲染组件。但更改引用不会！ 你通过ref.current 属性访问该引用的当前值。
                        */
                            import {useRef} from 'react';
                            export default function Counter(){
                                let ref = useRef(0);

                                function handleClick(){
                                    ref.current += 1;
                                    alert('You clicked '+re.current+'times');
                                }

                                return (
                                    <button onClick={handleClick}>
                                    Click me!
                                    </button>
                                );
                            }
                        /*
                            引用就像是React不跟踪的组件的"秘密口袋"。
                            例如，你可以使用引用来存储 "超时ID"  、DOM元素 和其他不影响组件渲染输出的对象
                        */


                // 二、使用应用操作ＤＯＭ
                　　　  /*
                            React 会自创建新DOM以匹配你的渲染输出，因此你的组件不需要经常操作它。
                            但是，有时你可能需要访问由React管理的DOM元素，例如，聚焦节点、滚动到它或测量其大小和位置。 
                            在React中没有内置的方法来做这些事情，所以，你需要一个对DOM节点的引用。
                        */
                            // 例如，单击按钮将使用引用聚焦输入：
                                    import {useRef} from 'react';
                                    export default function Form(){
                                        const inputRef =useRef(null);

                                        function handleClick(){
                                            inputRef.current.focus();
                                        }

                                        return (
                                            <>
                                                <input ref={inputRef}/>

                                                <button onClick={handleClick}>
                                                    Focus the input!
                                                </button>
                                            </>
                                        );
                                    }


                // 三、使用副作用进行同步。

                         /*
                             一些组件需要与外部系统同步。例如，你可能希望根据React状态控制非React组件、设置服务器连接或在组件出现在屏幕上时发送分析日志。

                             与让你处理特定事件的事件处理程序不同，"副作用"让你"在渲染后运行一些代码"。使用副作用将你的组件与React之外的系统同步。
                         */

                            import { useState, useRef, useEffect } from 'react';

                            function VideoPlayer({ src, isPlaying }) {
                                const ref = useRef(null);

                                useEffect(() => {
                                    if (isPlaying) {
                                        ref.current.play();
                                    } else {
                                        ref.current.pause();
                                    }
                                }, [isPlaying]);

                                return <video ref={ref} src={src} loop playsInline />;
                            }

                            export default function App() {
                                const [isPlaying, setIsPlaying] = useState(false);
                                return (
                                    <>
                                        <button onClick={() => setIsPlaying(!isPlaying)}>
                                            {isPlaying ? 'Pause' : 'Play'}
                                        </button>
                                        <VideoPlayer
                                            isPlaying={isPlaying}
                                            src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
                                        />
                                    </>
                                );
                            }


                
                // 四、你可能不需要副作用
                        /*
                            副作用是React典型的应急方案。
                            它们让你天眼React的"走出"，并让你的组件与一些外部系统同步。
                            如果不涉及外部系统(例如，如果你想在某些属性或状态更改时更新组件的状态)，则不需要副作用。
                            删除不必要的副作用，将使你的代码更易于理解、运行速度快并且不容易出错。

                            有两种情况不需要副作用：
                                ①、你不需要副作用来转换数据以进行渲染。
                                ②、你不需要副作用来处理用户事件。
                        */

                            // 例如： 你不需要副作用来根据其他状态调整某些状态：
                                function Form() {
                                    const [firstName, setFirstName] = useState('Taylor');
                                    const [lastName, setLastName] = useState('Swift');

                                    // 🔴 Avoid: redundant state and unnecessary Effect
                                    const [fullName, setFullName] = useState('');
                                    useEffect(() => {
                                        setFullName(firstName + ' ' + lastName);
                                    }, [firstName, lastName]);
                                    // ...
                                }
                                // 不需要这样，而是在渲染时尽可能的计算fullName

                        // 但是，你确实需要副作用才能与外部系统同步。


                
                                

    </script>
</html>